package com.hk.demo.player.http;


import com.hk.player.core.DataCallback;
import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.ObservableSubscribeProxy;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;
import com.zhoug.common.content.Optional;
import com.zhoug.common.framework.eventbus.EventBusUtils;
import com.zhoug.common.framework.eventbus.EventMessage;
import com.zhoug.common.framework.rxjava2.SchedulerUtils;
import com.zhoug.common.utils.LogUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import androidx.lifecycle.LifecycleOwner;
import io.reactivex.Observable;
import io.reactivex.disposables.Disposable;
import okhttp3.Call;
import okhttp3.Dispatcher;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;

/**
 * @Author: 35574
 * @Date: 2022/7/14
 * @Description:
 */
public class HttpClient {
    private static final String TAG = ">>>HttpClient";
    private static boolean debug = true;
    private Retrofit retrofit;
    private BaseRequests baseRequests;
    private static HttpClient instance;
    private EventBusReceiver eventBusReceiver;//baseUrl改变后事件监听器
    public static final int CHANGE_SERVER = 156;//服务器改变的EventMessage
    private HttpClient() {
        init();
    }

    public static HttpClient getInstance() {
        if (instance == null) {
            synchronized (HttpClient.class) {
                if (instance == null) {
                    instance = new HttpClient();
                }
            }
        }
        return instance;
    }

    /**
     * 初始化
     */
    private void init() {
        MyHttpLogInterceptor logInterceptor = new MyHttpLogInterceptor();
        if (debug) {
            logInterceptor.setLevel(MyHttpLogInterceptor.Level.BODY);
        } else {
            logInterceptor.setLevel(MyHttpLogInterceptor.Level.NONE);
        }

        String baseUrl = DataManager.getApiV1();
        retrofit = new MyRetrofitBuilder()
                .setDebug(debug)
                .setDebugLevel(null)
                .setConnectTimeOut(30)
                .setReadTimeOut(120)
                .setWriteTimeOut(120)
                .addInterceptor(new TokenInterceptor())
                .addInterceptor(logInterceptor)
                .addInterceptor(new EncryptInterceptor(true,true))//
                .build(baseUrl);
        //注册监听
        //注册监听
        eventBusReceiver = new EventBusReceiver();
        eventBusReceiver.registerEventBus();
        LogUtils.d(TAG, "init:初始化:" + baseUrl);

    }

    /**
     * BaseRequests请求接口
     *
     * @return
     */
    public BaseRequests getBaseRequests() {
        if (baseRequests == null) {
            synchronized (this) {
                if (baseRequests == null) {
                    baseRequests = getRequest(BaseRequests.class);
                }
            }
        }
        return baseRequests;
    }

    /**
     * 创建请求接口
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T> T getRequest(Class<T> cls) {
        if (retrofit == null) {
            init();
        }
        return retrofit.create(cls);
    }


    private void _release(){
        cancelAllRequest();
        retrofit = null;
        baseRequests = null;
        if (eventBusReceiver != null) {
            eventBusReceiver.unregisterEventBus();
            eventBusReceiver = null;
        }
    }

    /**
     * 释放资源
     * 重置BaseUrl
     */
    public static void release() {
        if (instance != null) {
            instance._release();
            instance = null;
        }
    }


    /**
     * 取消全部请求
     */
    public void cancelAllRequest() {
        if (retrofit != null) {
            Call.Factory factory = retrofit.callFactory();
            if (factory instanceof OkHttpClient) {
                OkHttpClient okHttpClient = (OkHttpClient) factory;
                Dispatcher dispatcher = okHttpClient.dispatcher();
                if (dispatcher != null) {
                    if (debug) {
                        LogUtils.d(TAG, "cancelAllRequest:取消全部请求");
                    }
                    dispatcher.cancelAll();
                }
            }
        }
    }

    public static void setDebug(boolean debug) {
        HttpClient.debug = debug;
    }

    public static boolean isDebug() {
        return debug;
    }

    public static <T> ObservableSubscribeProxy<Optional<T>> handler(Observable<HttpBaseResponse<T>> observable, LifecycleOwner lifecycleOwner) {
        return observable.compose(SchedulerUtils.apply())
                .compose(ResponseTransformer.handleResult())
                .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)));

    }

    public static <T> Observable<Optional<T>> handler(Observable<HttpBaseResponse<T>> observable) {
        return observable.compose(SchedulerUtils.apply())
                .compose(ResponseTransformer.handleResult());
    }

    public static <T> Disposable handler(Observable<HttpBaseResponse<T>> observable, DataCallback<T> callback) {
//        Observable<Optional<T>> compose = observable.compose(SchedulerUtils.apply())
//                .compose(ResponseTransformer.handleResult());
        return observable.compose(SchedulerUtils.apply())
                .compose(ResponseTransformer.handleResult())
                .subscribe(s -> {
                    if (callback != null) {
                        callback.onSuccess(s.get());
                    }
                }, throwable -> {
                    if (callback != null) {
                        callback.onFailure(throwable.getMessage());
                    }
                });
    }

    public static final class EventBusReceiver {

        private void registerEventBus() {
            EventBusUtils.register(this);
        }

        @Subscribe(threadMode = ThreadMode.MAIN)
        public void onReceiver(EventMessage eventMessage) {
            if (eventMessage != null && eventMessage.getType() == CHANGE_SERVER) {
                release();
            }
        }

        private void unregisterEventBus() {
            EventBusUtils.unregister(this);
        }
    }

}
